package com.vaadin.lab9;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

import com.vaadin.Application;
import com.vaadin.data.Container;
import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Container.ItemSetChangeListener;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.CellStyleGenerator;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

@SuppressWarnings("serial")
public class Lab extends Application {

    private SimpleDateFormat dateFormat = new SimpleDateFormat("MMM", Locale.US);
    private ObjectProperty<Integer> monthlyTarget = new ObjectProperty<Integer>(
            0);

    @Override
    public void init() {
        Window mainWindow = new Window("Lab");
        setMainWindow(mainWindow);

        final Table table = new Table("Report") {
            @Override
            protected String formatPropertyValue(Object rowId, Object colId,
                    Property property) {
                if (property.getValue() != null && colId.equals("month")) {
                    return dateFormat.format(property.getValue());
                }
                return super.formatPropertyValue(rowId, colId, property);
            }
        };

        TextField target = new TextField("Monthly target", monthlyTarget);
        target.addValidator(new IntegerValidator("{0} must be an Integer"));
        target.addListener(new Property.ValueChangeListener() {

            @Override
            public void valueChange(ValueChangeEvent event) {
                table.refreshRowCache();
                Lab.this.setFooterColor(getTotalBilled(table), table);
            }
        });
        target.setImmediate(true);

        mainWindow.addComponent(target);

        table.setFooterVisible(true);

        table.setCellStyleGenerator(new CellStyleGenerator() {

            @Override
            public String getStyle(Object itemId, Object propertyId) {
                if ("billed".equals(propertyId)) {
                    Object value = table.getContainerProperty(itemId,
                            propertyId).getValue();
                    if (monthlyTarget.getValue().compareTo((Integer) value) > 0) {
                        return "red";
                    }
                }
                return null;
            }
        });

        table.addListener(new ItemSetChangeListener() {

            @Override
            public void containerItemSetChange(ItemSetChangeEvent event) {
                int total = getTotalBilled(table);
                setFooterColor(total, table);
                table.setColumnFooter("billed", String.valueOf(total));
            }
        });

        mainWindow.addComponent(table);
        setTheme("budapestlabstheme");
        populateTable(table);

    }

    private void populateTable(Container container) {
        container.addContainerProperty("month", Date.class, null);
        container.addContainerProperty("billed", Integer.class, null);
        Random rand = new Random(1L);
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(Calendar.YEAR, 2012);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        for (int i = 0; i < 12; i++) {
            Object id = container.addItem();
            container.getContainerProperty(id, "month").setValue(cal.getTime());
            container.getContainerProperty(id, "billed").setValue(
                    rand.nextInt(400) + 100);
            cal.roll(Calendar.MONTH, true);
        }
    }

    private void setFooterColor(int total, final Table table) {
        if (total < monthlyTarget.getValue() * 12) {
            table.addStyleName("footer-red");
        } else {
            table.removeStyleName("footer-red");
        }
    }

    private int getTotalBilled(Container container) {
        int total = 0;
        for (Object itemId : container.getItemIds()) {
            Object value = container.getContainerProperty(itemId, "billed")
                    .getValue();
            if (value != null) {
                total += (Integer) value;
            }

        }
        return total;
    }

}
